package com.ctg.itrdc.imageconsole.service.deploy;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import com.ctg.itrdc.imageconsole.data.dao.IClusterConfigDao;
import com.ctg.itrdc.imageconsole.data.dao.IDockerMicroGroupDao;
import com.ctg.itrdc.imageconsole.data.dao.IDockerMicroGroupDetailDao;
import com.ctg.itrdc.imageconsole.data.dto.DMSGroupAndNodeDTO;
import com.ctg.itrdc.imageconsole.data.dto.DMSParamGroupDTO;
import com.ctg.itrdc.imageconsole.data.dto.DMSReturnGroupDTO;
import com.ctg.itrdc.imageconsole.data.entity.DockerMicroGroup;
import com.ctg.itrdc.imageconsole.data.entity.DockerMicroGroupDetail;
import com.ctg.itrdc.imageconsole.util.KubeUtils;
import com.ctg.itrdc.paspsdk.common.entity.PageInfo;
import com.ctg.itrdc.paspsdk.data.dao.IBaseDao;


/*
 * 			Author			Date			Operation
 * 			Shizhu.Peng		2017-03-06		update
 * 
 */


@Component("groupManager")
public class GroupManager {	
	
	@Resource
	IBaseDao baseDao;
	
	@Resource
	IDockerMicroGroupDao groupDao;	
	
	@Resource
	IDockerMicroGroupDetailDao groupDetailDao;
	
	@Resource
	IClusterConfigDao clusterConfigDao;
	
	public boolean groupExist(String k8sCode, String GroupCode)
	{
		DockerMicroGroup group = groupDao.selectByK8sCodeAndGroupCode(k8sCode, GroupCode);
		return null != group;
	}
	
	public PageInfo<DMSReturnGroupDTO> getGroups(String k8sCode, String groupCode, Integer pageNum, Integer pageSize) 
	{
		String sql = "select id as groupId, group_code as groupCode from docker_micro_group" +
				" where k8s_code = ? and group_code like ?";
		List<Object> params = new ArrayList<>();
		
		params.add(k8sCode);	
		if(null == groupCode)
			params.add("%");
		else
			params.add("%" + groupCode + "%");
		if(null == pageNum || null == pageSize)
			throw new RuntimeException("Error : pageNum or pageSize is null");
		return baseDao.jdbcFindPageInfo(sql, DMSReturnGroupDTO.class, params, pageNum, pageSize);	
	}
	
	public PageInfo<DMSGroupAndNodeDTO> getGroupsAndItsNodes(String k8sCode, String groupCode, Integer pageNum, Integer pageSize) 
	{
		String sql = "select id as groupId, group_code as groupCode from docker_micro_group" +
				" where k8s_code = ? and group_code like ?";
		List<Object> params = new ArrayList<>();
		
		params.add(k8sCode);	
		if(null == groupCode)
			params.add("%");
		else
			params.add("%" + groupCode + "%");
		
		PageInfo<DMSGroupAndNodeDTO> pageInfo = baseDao.jdbcFindPageInfo(sql, DMSGroupAndNodeDTO.class, params, pageNum, pageSize);
		List<DMSGroupAndNodeDTO> list = pageInfo.getList();
		
		for(DMSGroupAndNodeDTO dto : list)
		{
			String sql1 = "select node_name from docker_micro_group_detail" +
						" where docker_micro_group_id = ?";
			List<Object> params1 = new ArrayList<>();
			params1.add(dto.getGroupId());
			List<String> nodeNameList = baseDao.jdbcFindList(sql1, String.class, params1);
			dto.setNodeNameList(nodeNameList);
		}
		return pageInfo;
	}
	
	/*
	 * Last updated : Shizhu.Peng, Jan 11
	 */
	public void updateGroup(Long dockerMicroGroupId, String newGroupCode, List<String> nodeList) 
	{
		// 1 : update group_code in db table docker_micro_group
		DockerMicroGroup group = groupDao.selectById(dockerMicroGroupId);
		if(!newGroupCode.equals(group.getGroupCode()))
		{
			DockerMicroGroup group1 = groupDao.selectByK8sCodeAndGroupCode(group.getK8sCode(), newGroupCode);
			if(null != group1)
				throw new RuntimeException("Group " + newGroupCode + " already exists");
			groupDao.updateGroupCode(dockerMicroGroupId, newGroupCode);
		}			
		
		// 2 : update node_name in db table docker_micro_group_detail
		List<DockerMicroGroupDetail> recordList = groupDetailDao.selectByDockerMicroGroupId(dockerMicroGroupId);
		List<String> nodeListInDb = new ArrayList<>(); // --- Better suggestion : use set instead of list --- //
		for(DockerMicroGroupDetail detail : recordList)
			nodeListInDb.add(detail.getNodeName());
		// 2.1 : delete from db
		for(String nodeName : nodeListInDb)  
		{
			if(!nodeList.contains(nodeName))
				groupDetailDao.deleteByDockerMicroGroupIdAndNodeName(dockerMicroGroupId, nodeName);
		}
		// 2.2 : add to db
		for(String nodeName : nodeList)
		{
			if(!nodeListInDb.contains(nodeName))
				groupDetailDao.insert(dockerMicroGroupId, nodeName);
		}
		
		// 3 : update node Label
		String apiServerUrl = clusterConfigDao.selectApiServerUrlByClusterCode(group.getK8sCode());
		if(newGroupCode.equals(group.getGroupCode())) // groupCode does not change
		{
			// 3.1 : delete nodes from group
			for(String nodeName : nodeListInDb)  
			{
				if(!nodeList.contains(nodeName))
					KubeUtils.deleteLabelOfNode(apiServerUrl, nodeName, group.getGroupCode());
			}
			// 3.2 : add to nodes to group
			for(String nodeName : nodeList)
			{			 
				if(!nodeListInDb.contains(nodeName))
				{
					String keyValue = newGroupCode;
					KubeUtils.addLabelToNode(apiServerUrl, nodeName, keyValue, keyValue);
				}
			}
		}
		else	// groupCode has changed
		{
			// 3.1 : delete from node labels
			for(String nodeName : nodeListInDb)  
				KubeUtils.deleteLabelOfNode(apiServerUrl, nodeName, group.getGroupCode());
			// 3.2 : add to node labels
			for(String nodeName : nodeList)
			{
				String keyValue = newGroupCode;
				KubeUtils.addLabelToNode(apiServerUrl, nodeName, keyValue, keyValue);
			}
		}		
	}
	
		
	/*
	 * 		Date			Author			Operation
	 * 		2017.01.11		Shizhu.Peng		Created
	 */		
	public void addGroup(DMSParamGroupDTO dto) 
	{		 		
		String apiServerUrl = clusterConfigDao.selectApiServerUrlByClusterCode(dto.getK8sCode());
		DockerMicroGroup group = new DockerMicroGroup();		
		group.setK8sCode(dto.getK8sCode());
		group.setGroupCode(dto.getGroupCode());
		group.setCreateUserId(dto.getCreateUserId());
		group.setLastUpdateUserId(dto.getLastUpdateUserId());
		group.setCreateTime(dto.getCreateTime());
		group.setLastUpdateTime(dto.getLastUpdateTime());
		Long dockerMicroGroupId = groupDao.insert(group);
		// insert to db
		List<String> nodeList = dto.getNodeList();
		for(String nodeName : nodeList)
		{			
			groupDetailDao.insert(dockerMicroGroupId, nodeName);
		}				
		// insert to node labels
		for(String nodeName : nodeList)
		{			
		//	String nodeLabel = dto.getTenantCode() + "-" + dto.getGroupCode();
			String nodeLabel = dto.getGroupCode();
			KubeUtils.addLabelToNode(apiServerUrl, nodeName, nodeLabel, nodeLabel);
		}
	}

		
	
	
	public void deleteGroup(Long dockerMicroGroupId) 
	{
		DockerMicroGroup group = groupDao.selectById(dockerMicroGroupId);
		if(null == group)
			return;					
		List<DockerMicroGroupDetail> groupDetailList = groupDetailDao.selectByDockerMicroGroupId(group.getId());
		
		groupDao.deleteByPrimaryKey(group);
		groupDetailDao.deleteByDockerMicroGroupId(group.getId());
		
		String apiServerUrl = clusterConfigDao.selectApiServerUrlByClusterCode(group.getK8sCode());
		for(DockerMicroGroupDetail groupDetail : groupDetailList)
		{
			KubeUtils.deleteLabelOfNode(apiServerUrl, groupDetail.getNodeName(), group.getGroupCode());
		}		
	}
}


